Prevent dragging groups into groups. Fixes #8706
[adiumx.git] / Plugins / Dual Window Interface / ESChatUserListController.m
blob5600dc7deda8df0304a169ed2acd36f4d74ef1b7
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
11  * Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License along with this program; if not,
14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15  */
17 #import "ESChatUserListController.h"
18 #import <Adium/AIMenuControllerProtocol.h>
19 #import <Adium/AIMetaContact.h>
20 #import "AIMessageTabViewItem.h"
22 @implementation ESChatUserListController
24 /*!
25  * @brief Notify our delegate when the selection changes.
26  */
27 - (void)outlineViewSelectionDidChange:(NSNotification *)notification
29         if ([[self superclass] instancesRespondToSelector:@selector(outlineViewSelectionDidChange:)]) {
30                 [super outlineViewSelectionDidChange:notification];
31         }
32         
33         if ([[self delegate] respondsToSelector:@selector(outlineViewSelectionDidChange:)]) {
34                 [[self delegate] performSelector:@selector(outlineViewSelectionDidChange:)
35                                                           withObject:notification];
36         }
39 /*!
40  * @brief We don't want to change text colors based on the user's status or state
41  *
42  * This is called by our superclass during configuration.
43  */
44 - (BOOL)shouldUseContactTextColors
46         return NO;
49 /*!
50  * @brief Use the status message for a contact, not its calculated extended status, in the group chat user list
51  *
52  * This is called by our superclass during configuration.
53  */
54 - (BOOL)useStatusMessageAsExtendedStatus
56         return YES;
59 #pragma mark Drag & drop
61 /*!
62  * @brief Accept a drop
63  *
64  * When a drop of a contact is performed onto the user list, invite the contact to the chat
65  */
66 - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index
68         //Invite the dragged contact(s) to the chat
69         BOOL                    success = NO;
70         AIChat                  *activeChat = [[adium interfaceController] activeChatInWindow:[info draggingDestinationWindow]];
71         AIAccount               *activeChatAccount = [activeChat account];
72         NSEnumerator    *enumerator = [[self draggedContacts] objectEnumerator];
73         AIListObject    *listObject;
74         
75         while ((listObject = [enumerator nextObject])) {
76                 if ([listObject isKindOfClass:[AIMetaContact class]]) {
77                         listObject = [(AIMetaContact *)listObject preferredContactWithCompatibleService:[activeChatAccount service]];
78                 }
80                 if ([listObject isKindOfClass:[AIListContact class]] &&
81                         [[listObject serviceClass] isEqualToString:[activeChatAccount serviceClass]]) {
82                         [activeChatAccount inviteContact:(AIListObject *)listObject toChat:activeChat withMessage:nil];
83                         success = YES;
84                 }
85         }
87         success = [super outlineView:outlineView acceptDrop:info item:item childIndex:index] && success;
88         
89         return success;
92 /*!
93  * @brief Validate a drop
94  *
95  * We can use setDropItem:dropChildIndex: to reposition the drop.
96  *
97  * @param outlineView The outline view which will receive the drop
98  * @param info The NSDraggingInfo
99  * @param item The item into which the drag would currently drop
100  * @param index The index within item into which the drag would currently drop. It may be a 0-based index inside item or may be NSOutlineViewDropOnItemIndex.
101  * @result The drag operation we will allow
102  */
103 - (NSDragOperation)outlineView:(NSOutlineView*)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index
105         NSEnumerator    *enumerator = [[self draggedContacts] objectEnumerator];
106         AIListObject    *listObject;
107         AIChat                  *activeChat = [[adium interfaceController] activeChatInWindow:[info draggingDestinationWindow]];
108         AIAccount               *activeChatAccount = [activeChat account];
110         while ((listObject = [enumerator nextObject])) {
111                 if ([listObject isKindOfClass:[AIMetaContact class]]) {
112                         listObject = [(AIMetaContact *)listObject preferredContactWithCompatibleService:[activeChatAccount service]];
113                 }
115                 if ([listObject isKindOfClass:[AIListContact class]] &&
116                         [[listObject serviceClass] isEqualToString:[activeChatAccount serviceClass]]) {
117                         return NSDragOperationCopy;
118                 }
119         }
120         
121         return NSDragOperationNone;
124 #pragma mark Contextual menu
127  * @brief Return the contextual menu for a passed list object
129  * Assumption: Our delegate is an AIMessageTabViewItem (which responds to chat)
130  */
131 - (NSMenu *)contextualMenuForListObject:(AIListObject *)listObject
133         NSArray                 *locationsArray = [NSArray arrayWithObjects:
134                 [NSNumber numberWithInt:Context_Contact_GroupChatAction],               
135                 [NSNumber numberWithInt:Context_Contact_Manage],
136                 [NSNumber numberWithInt:Context_Contact_Action],
137                 [NSNumber numberWithInt:Context_Contact_ListAction],
138                 [NSNumber numberWithInt:Context_Contact_NegativeAction],
139                 [NSNumber numberWithInt:Context_Contact_Additions], nil];
140         
141     return [[adium menuController] contextualMenuWithLocations:locationsArray
142                                                                                                  forListObject:listObject
143                                                                                                                 inChat:[[self delegate] chat]];
146 @end